/*
-----------------------------------------------------------------------------
This source file is part of SapphireEngine

SapphireEngine is a Framework for Turn Based Strategy games.
For more information see http://code.google.com/p/sapphire-engine/

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

-----------------------------------------------------------------------------
*/
#ifndef _PART_TOOL_SCREEN_H
#define _PART_TOOL_SCREEN_H

#include "SapphirePrerequisites.h"

#include "SapphireEngineApp.h"
#include "Core/CoreManager.h"
#include "Core/Part.h"

#include "mysql_connection.h"

#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>

#include <CEGUI/CEGUI.h>
#include <OIS/OIS.h>
#include <OgreCEGUIRenderer.h>
#include <list>

#include "SapphireMemoryManager.h"

#define PI 3.14
#define ROTATESTEP PI/120
#define DOLLYSTEP 0.25

using namespace SapphireEngine::Core;

namespace SapphireEngine
{
	namespace GUI
	{
		class PartTool : public Screen
		{
		public:
			PartTool():mEntity(0),mRotate(false),mDolly(false),mPart(0),mOverWrite(true)
			{
				_setupScene();
				_renderToTex();
				//----add to Tab List the screen elements------------------------------
				Window* wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/MeshBar");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Name");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Description");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/SubType");
				mTabList.push_back(wnd);
		// 		wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechFirst");
		// 		mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl");
				mTabList.push_back(wnd);
		// 		wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechSecond");
		// 		mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl1");
				mTabList.push_back(wnd);
		// 		wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechThird");
		// 		mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl2");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/HitPoints");
				mTabList.push_back(wnd);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Points");
				mTabList.push_back(wnd);
				//----add to Tab List the screen elements------------------------------

				//fill game factors and add the new labels to the tab list
				//-------------------------------------------------------------------------------------------------------------------------------------------------
				const StringSet* DamageTypes = getCoreManager()->getDamageTypes();
				_initFactor(DamageTypes,"Armor");
				const StringSet* TerrainTypes = getCoreManager()->getTerrainTypes();
				_initFactor(TerrainTypes,"Move");
				_initFactor(DamageTypes,"Damage");				

				//fill part type combobox
				const StringSet* partTypes = getCoreManager()->getPartTypes();
				Combobox *cmbo = (Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				Combobox *cmboNode = (Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/NodePanel/Type");
				for (StringSetConstIterator itr = partTypes->begin();itr != partTypes->end();itr++)
				{
					ListboxTextItem* itemCombobox = new ListboxTextItem(*itr);
					mListItems.push_back(itemCombobox);
					getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
					cmbo->addItem(itemCombobox);
					itemCombobox = new ListboxTextItem(*itr);
					mListItems.push_back(itemCombobox);
					getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
					cmboNode->addItem(itemCombobox);
				}
				
				//fill part sub type combobox
				const StringSet* partSubTypes = getCoreManager()->getPartSubTypes();
				cmbo = (Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/SubType");
				cmboNode = (Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/NodePanel/SubType");
				for (StringSetConstIterator itr = partSubTypes->begin();itr != partSubTypes->end();itr++)
				{
					ListboxTextItem* itemCombobox = new ListboxTextItem(*itr);
					mListItems.push_back(itemCombobox);
					getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
					cmbo->addItem(itemCombobox);
					itemCombobox = new ListboxTextItem(*itr);
					mListItems.push_back(itemCombobox);
					getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
					cmboNode->addItem(itemCombobox);
				}

				//fill Technology combobox
				AddTechnology((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechFirst");
				AddTechnology((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechSecond");
				AddTechnology((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechThird");
				
				//AddParts((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/ExistingParts");

				mCurrentTab =mTabList.begin();
				wnd = *mCurrentTab;
				wnd->activate();

				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveBtn");
				wnd->setEnabled(false);
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveNewBtn");
				wnd->setEnabled(false);

				saved=true;
				canSave=false;
			}
			~PartTool()
			{
				if (mPart)
				{
					getMemoryManager()->removePointer(mPart);
					delete mPart;
				}
				for(std::vector<ListboxTextItem*>::iterator itr=mListItems.begin();itr!=mListItems.end();itr++)
				{
					getMemoryManager()->removePointer(*itr);
//					delete *itr;
				}
				unSubscribeEvents();
			}
			//-----------------Add Technologies to the combobox from the database------------------------------------------------
			void AddTechnology(CEGUI::String str)
			{
				const TechnologyMap* technologies = getCoreManager()->getTechnologies();
				Combobox *cmboTech = (Combobox*)getWindowManager()->getWindow(str);

				ListboxTextItem* itemCombobox = new ListboxTextItem("");
				mListItems.push_back(itemCombobox);
				getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
				cmboTech->addItem(itemCombobox);

				for (TechnologyMapConstIterator itr = technologies->begin();itr != technologies->end();itr++)
				{
					itemCombobox = new ListboxTextItem(itr->second->getName());
					mListItems.push_back(itemCombobox);
					getMemoryManager()->addPointer(itemCombobox,"ListBox Item");
					cmboTech->addItem(itemCombobox);
				}
			}
			//-----------------Add Technologies to the combobox from the database------------------------------------------------

			void subscribeEvents()
			{
				CEGUI::Event::Connection connect;

				Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/LoadBtn");
				connect = wnd->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&PartTool::_loadModel, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveNewBtn");
				connect = wnd->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&PartTool::_saveNewPart, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveBtn");
				connect = wnd->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&PartTool::_updatePart, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				connect = wnd->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted,CEGUI::Event::Subscriber(&PartTool::_showFactors, this));
				mEventConnections.push_front(connect);	

				//general
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Name");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Description");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/SubType");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechFirst");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechSecond");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechThird");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl1");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl2");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/HitPoints");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Points");
				connect = wnd->subscribeEvent(CEGUI::Window::EventDeactivated,CEGUI::Event::Subscriber(&PartTool::_update, this));
				mEventConnections.push_front(connect);

				//factor events
				//-----------------------------------------------------------------------------------------
				//Armor
				int factorLen = (int)getCoreManager()->getDamageTypes()->size();
				for(int i=1;i<=factorLen;i++)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Val");
					connect = wnd->subscribeEvent(Editbox::EventTextChanged,CEGUI::Event::Subscriber(&PartTool::_updateFactors, this));
					mEventConnections.push_front(connect);
				}
				//Damage
				for(int i=1;i<=factorLen;i++)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Val");
					connect = wnd->subscribeEvent(Editbox::EventTextChanged,CEGUI::Event::Subscriber(&PartTool::_updateFactors, this));
					mEventConnections.push_front(connect);
				}
				//Movement
				factorLen = (int)getCoreManager()->getTerrainTypes()->size();
				for(int i=1;i<=factorLen;i++)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Val");
					connect = wnd->subscribeEvent(Editbox::EventTextChanged,CEGUI::Event::Subscriber(&PartTool::_updateFactors, this));
					mEventConnections.push_front(connect);
				}
				//-----------------------------------------------------------------------------------------
			}
			// MouseListener
			bool mouseMoved(const OIS::MouseEvent &arg)
			{
				if(arg.state.buttonDown(OIS::MB_Left))
					if(mRotate)
					{
						//Heading
						mCamParent->rotate(Ogre::Vector3::UNIT_Y,Radian(ROTATESTEP*arg.state.X.rel*-1),Node::TS_PARENT);
						//Pitch
						mCamParent->rotate(Ogre::Vector3::UNIT_X,Radian(ROTATESTEP*arg.state.Y.rel),Node::TS_PARENT);
					}
					else if(mDolly)
					{
						Ogre::Vector3 vec=mCamera->getPosition();
						vec.z-=arg.state.Y.rel*DOLLYSTEP;
						if(vec.z > -8)
							vec.z = -8;
						else if(vec.z < -20)
							vec.z = -20;									
						mCamera->setPosition(vec);
					}
				return true;
			}
			// KeyListener
			bool keyPressed(const OIS::KeyEvent &arg)
			{
				if (arg.key == OIS::KC_LMENU)
					mRotate=true;
				if (arg.key == OIS::KC_LCONTROL)
					mDolly = true;				
				if (arg.key == OIS::KC_ESCAPE)
					mContinue=false;
				if (arg.key == OIS::KC_TAB)
					{
						mCurrentTab++;
						if(mCurrentTab==mTabList.end())
							mCurrentTab=mTabList.begin();
						CEGUI::Window *wnd= *mCurrentTab;
						while(wnd->isVisible()==false)
						{
							mCurrentTab++;
							if(mCurrentTab==mTabList.end())
								mCurrentTab=mTabList.begin();
							wnd = *mCurrentTab;
						}
						wnd->activate();
					}
				return true;
			}
			bool keyReleased(const OIS::KeyEvent &arg)
			{
				if (arg.key == OIS::KC_LMENU)
					mRotate=false;
				if (arg.key == OIS::KC_LCONTROL)
					mDolly=false;
				return true;
			}
			bool update(const FrameEvent &evt)
			{
				if(canSave)
				{
					CEGUI::Window* wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveNewBtn");
					wnd->setEnabled(true);
					if (mPart->getID()!=-1)
					{
						CEGUI::Window* wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveBtn");
						wnd->setEnabled(true);
					}
				}
				return mContinue;
			}
		private:
			void _setupScene()
			{
				mSceneMgr = Root::getSingletonPtr()->createSceneManager(ST_GENERIC,"Part SceneManager");

				mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
				mCamParent = mSceneMgr->getRootSceneNode()->createChildSceneNode();

				mCamera = mSceneMgr->createCamera("Camera");
				mCamera->setFarClipDistance(300);
				mCamera->setNearClipDistance(3);
				mCamParent->attachObject(mCamera);
				mCamera->setPosition(0,2,-20);
				mCamera->lookAt(0,2,0);

				mSceneMgr->setAmbientLight(Ogre::ColourValue(0.05, 0.05, 0.05));   

				Light *light = mSceneMgr->createLight("KeyLight");
				light->setType(Light::LT_SPOTLIGHT);
				light->setDiffuseColour(0.8, 0.8, 0.49);//LightYellow
				light->setSpecularColour(1.0, 1.0, 1.0);//White

				light->setDirection(-0.33, -1, 0.66);
				light->setPosition(Ogre::Vector3(25, 75, -50));

				light->setSpotlightRange(Degree(35), Degree(50));
				mCamParent->attachObject(light);

				light = mSceneMgr->createLight("FillLight");
				light->setType(Light::LT_SPOTLIGHT);
				light->setDiffuseColour(0.29, 0.35, 0.5);//LightBlue
				light->setSpecularColour(1.0, 1.0, 1.0);//White

				light->setDirection(0.5, -1, 1);
				light->setPosition(Ogre::Vector3(-25, 50, -50));

				light->setSpotlightRange(Degree(35), Degree(50));
				mCamParent->attachObject(light);

				light = mSceneMgr->createLight("BackLight");
				light->setType(Light::LT_SPOTLIGHT);
				light->setDiffuseColour(1.0, 1.0, 1.0);//White
				light->setSpecularColour(1.0, 1.0, 1.0);//White

				light->setDirection(0.5, -1, -1);
				light->setPosition(Ogre::Vector3(-25, 50, 50));

				light->setSpotlightRange(Degree(35), Degree(50));
				mCamParent->attachObject(light);
			}
			void _renderToTex()
			{
				Ogre::RenderTexture *tex= Ogre::Root::getSingletonPtr()->getTextureManager()->createManual
										  ("Part", "Default", TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET)
										   ->getBuffer()->getRenderTarget();

				Viewport *v = tex->addViewport(mCamera);
				v->setOverlaysEnabled(false);
				v->setClearEveryFrame(true);
				v->setBackgroundColour(ColourValue::Black);

				CEGUI::Texture *cTex = static_cast<CEGUI::OgreCEGUIRenderer*>(getSystem()->getRenderer())->createTexture((CEGUI::utf8*)"Part");

				CEGUI::Imageset *imageSet = CEGUI::ImagesetManager::getSingleton().createImageset((CEGUI::utf8*)"PartImageset", cTex);
				imageSet->defineImage((CEGUI::utf8*)"PartImage", 
				   CEGUI::Point(0.0f, 0.0f),
				   CEGUI::Size(cTex->getWidth(), cTex->getHeight()),
				   CEGUI::Point(0.0f,0.0f));

				Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PartView");
				wnd->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet->getImage((CEGUI::utf8*)"PartImage")));
			}
			void _initFactor(const StringSet* factorTypes, Ogre::String factor)
			{
				Window *wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String(factor));
				StringSetConstIterator itr = factorTypes->begin();
				for(unsigned int i=1;i<=factorTypes->size();i++)
				{
					Window *element = getWindowManager()->createWindow((CEGUI::utf8*)"DefaultWindow","Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String(factor)+"/Elem"+i);
					element->setArea(CEGUI::UDim(0,0),CEGUI::UDim((i-1)*0.23,0),CEGUI::UDim(0.9,0),CEGUI::UDim(0.23,0));
					wnd->addChildWindow(element);
					
					Window *SubElement = getWindowManager()->createWindow((CEGUI::utf8*)"TaharezLook/StaticText","Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String(factor)+"/Elem"+i+"/Lbl");
					SubElement->setProperty("Font","Ariel-8");
					SubElement->setProperty("Text",*itr++);
					SubElement->setProperty("FrameEnabled","False");
					SubElement->setArea(CEGUI::UDim(0.05,0),CEGUI::UDim(0,0),CEGUI::UDim(0.7,0),CEGUI::UDim(0.35,0));
					SubElement->setProperty("BackgroundEnabled","False");
					element->addChildWindow(SubElement);
					
					SubElement = (ProgressBar *)getWindowManager()->createWindow((CEGUI::utf8*)"TaharezLook/ProgressBar","Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String(factor)+"/Elem"+i+"/Bar");
					SubElement->setProperty("Font","Ariel-8");
					SubElement->setProperty("StepSize","0.01");
					SubElement->setProperty("CurrentProgress","0");
					SubElement->setArea(CEGUI::UDim(0,0),CEGUI::UDim(0.35,0),CEGUI::UDim(0.7,0),CEGUI::UDim(0.6,0));
					element->addChildWindow(SubElement);

					SubElement = getWindowManager()->createWindow((CEGUI::utf8*)"TaharezLook/Editbox","Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String(factor)+"/Elem"+i+"/Val");
					SubElement->setProperty("Font","Ariel-8");
					SubElement->setProperty("MaxTextLength","3");
					SubElement->setProperty("ValidationString","^\\d*$");
					SubElement->setArea(CEGUI::UDim(0.7,0),CEGUI::UDim(0.35,0),CEGUI::UDim(0.3,0),CEGUI::UDim(0.6,0));
					element->addChildWindow(SubElement);
					mTabList.push_back(SubElement);
				}
			}
			bool _loadModel(const CEGUI::EventArgs & arg)
			{
				if (!saved)
					return true;
				if(mEntity)
				{
					mNode->detachObject(mEntity);
					mSceneMgr->destroyEntity(mEntity);
				}
				if (mPart)
				{
					//clearScreen, ask to save
					getMemoryManager()->removePointer(mPart);
					delete mPart;
				}
				Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/MeshBar");
				Ogre::String meshFile(wnd->getText().c_str());
				if (meshFile.find(".mesh")==meshFile.npos)
					return false;
				mEntity = mSceneMgr->createEntity("Part", meshFile);
				mNode->attachObject(mEntity);

				mPart = new Body(-1,"","","",mEntity->getMesh()->getName(),0,0);
				getMemoryManager()->addPointer(mPart,"Part");

				//setDeafultData();

				/*wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/SaveBtn");
				wnd->setEnabled(true);*/
				return true;
			}
			bool _savePartOld(const CEGUI::EventArgs & arg)
			{
				CEGUI::Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/MeshBar");
				Ogre::String meshFile(wnd->getText().c_str());
				//if (meshFile.find(".xml"))
				//{
					//Name
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Name");
					Ogre::String partName(wnd->getText().c_str()); 
					//Description
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Description");
					Ogre::String partDesc(wnd->getText().c_str());
					//SubType
					CEGUI::Combobox *cmbo = (CEGUI::Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/SubType");
					Ogre::String partSubType(cmbo->getText().c_str());
					//Mesh file
					Ogre::String partMesh(mEntity->getMesh()->getName().c_str());
					
					//Type
					cmbo = (CEGUI::Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
					Ogre::String partType(cmbo->getText().c_str());
					
					//Hit Points
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/HitPoints");
					long partHitPoints = atol(wnd->getText().c_str());
					
					//Combat Points
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Points");
					long partCombatPoints = atol(wnd->getText().c_str());

					//Write Part to database
					sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO parts(Name,Description,Type,SubType,HitPoints,CombatPoints,MeshFile) VALUES(?,?,?,?,?,?,?);");
					pstmt->setString(1,partName);
					pstmt->setString(2,partDesc);
					pstmt->setString(3,partType);
					pstmt->setString(4,partSubType);
					pstmt->setInt(5,partHitPoints);
					pstmt->setInt(6,partCombatPoints);
					pstmt->setString(7,partMesh);
					pstmt->execute();
					delete pstmt;

					Ogre::String str="SELECT MAX(ID) from parts;";
					sql::ResultSet *res = getCoreManager()->readSql(str);
					int partId;
					while(res->next())
						partId=res->getInt(1);
					delete res;

					getMemoryManager()->removePointer(mPart);
					delete mPart;
					//Create Part Instance
					if (partType.compare("Weapon")==0)
					{
						mPart = new Weapon(partId,partName,partDesc,partSubType,partMesh,partHitPoints,partCombatPoints);
						getMemoryManager()->addPointer(mPart,"Part");
					}
					else if(partType.compare("Movement")==0)
					{
						mPart = new Movement(partId,partName,partDesc,partSubType,partMesh,partHitPoints,partCombatPoints);
						getMemoryManager()->addPointer(mPart,"Part");
					}
					else if(partType.compare("Body")==0)
					{
						mPart = new Body(partId,partName,partDesc,partSubType,partMesh,partHitPoints,partCombatPoints);
						getMemoryManager()->addPointer(mPart,"Part");
					}

					//Factors
					//-----------------------------------------------------------------
					//Armor
					int factorLen = (int)getCoreManager()->getDamageTypes()->size();
					for(int i=1;i<=factorLen;i++)
					{
						wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Lbl");
						CEGUI::Editbox *val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Val");
						Ogre::String factorType(wnd->getText().c_str());
						int factorVal = atol((char *)val->getText().c_str());
						mPart->setArmorByType(factorType,factorVal);
						pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_armor_factors(PartID,ArmorType,Factor) VALUES(?,?,?);");
						pstmt->setInt(1,partId);
						pstmt->setString(2,factorType);
						pstmt->setInt(3,factorVal);
						pstmt->execute();
						delete pstmt;
					}
					//Damage (if Weapon)
					if (cmbo->getSelectedItem()->getText().compare("Weapon")==0)
					{
						for(int i=1;i<=factorLen;i++)
						{
							wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Lbl");
							CEGUI::Editbox *val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Val");
							Ogre::String factorType(wnd->getText().c_str());
							int factorVal = atol((char *)val->getText().c_str());
							static_cast<Weapon *>(mPart)->setDamageByType(factorType,factorVal);
							pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_damage_factors(PartID,DamageType,Factor) VALUES(?,?,?);");
							pstmt->setInt(1,partId);
							pstmt->setString(2,factorType);
							pstmt->setInt(3,factorVal);
							pstmt->execute();
							delete pstmt;
						}
					}
					//Speed
					factorLen = (int)getCoreManager()->getTerrainTypes()->size();
					for(int i=1;i<=factorLen;i++)
					{
						wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Lbl");
						CEGUI::Editbox *val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Val");
						Ogre::String factorType(wnd->getText().c_str());
						int factorVal = atol((char *)val->getText().c_str());
						mPart->setSpeedByTerrain(factorType,factorVal);
						pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_speed_factors(PartID,TerrainType,Factor) VALUES(?,?,?);");
						pstmt->setInt(1,partId);
						pstmt->setString(2,factorType);
						pstmt->setInt(3,factorVal);
						pstmt->execute();
						delete pstmt;
					}
					//------------------------------------------------------------------
					//Technologies
					mPart->clearTechnologies();
					UpdatePartTechnologies(partId,(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechFirst",(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl");
					UpdatePartTechnologies(partId,(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechSecond",(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl1");
					UpdatePartTechnologies(partId,(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechThird",(CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl2");
					
					//Child nodes
					//--------------------------------------------------------------
					for(PartNodeArrayIterator itr= mPartNodes.begin();itr!=mPartNodes.end();itr++)
					{
						Ogre::String nodeType = (*itr)->getType();
						Ogre::String nodeSubType = (*itr)->getSubType();
						Ogre::Vector3 nodePos = (*itr)->getPosition();
						Ogre::Quaternion nodeOrient = (*itr)->getOrientation();
						Ogre::Vector3 nodeScale = (*itr)->getScale();
						PartNode* node = new PartNode(nodeType,nodeSubType,nodePos,nodeOrient,nodeScale);
						getMemoryManager()->addPointer(node,"Part Node");
						mPart->addChildNode(node);
						pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_child_nodes(PartId,Type,SubType,NodePozX,NodePozY,NodePozZ \
							,NodeRotW,NodeRotX,NodeRotY,NodeRotZ,NodeSclX,NodeSclY,NodeSclZ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);");
						pstmt->setInt(1,partId);
						pstmt->setString(2,nodeType);
						pstmt->setString(3,nodeSubType);
						pstmt->setDouble(4,nodePos.x);
						pstmt->setDouble(5,nodePos.y);
						pstmt->setDouble(6,nodePos.z);
						pstmt->setDouble(7,nodeOrient.w);
						pstmt->setDouble(8,nodeOrient.x);
						pstmt->setDouble(9,nodeOrient.y);
						pstmt->setDouble(10,nodeOrient.z);
						pstmt->setDouble(11,nodeScale.x);
						pstmt->setDouble(12,nodeScale.y);
						pstmt->setDouble(13,nodeScale.z);
						pstmt->execute();
						delete pstmt;
					}
					//--------------------------------------------------------------

					getCoreManager()->addPart(mPart);
				return true;
			}
			bool _saveNewPart(const CEGUI::EventArgs & arg)
			{
				//Write Part to database
				sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO parts(Name,Description,Type,SubType,HitPoints,CombatPoints,MeshFile) VALUES(?,?,?,?,?,?,?);");
				pstmt->setString(1,mPart->getName());
				pstmt->setString(2,mPart->getDescriprion());
				pstmt->setString(3,mPart->getPartType());
				pstmt->setString(4,mPart->getPartSubType());
				pstmt->setInt(5,mPart->getHitPoints());
				pstmt->setInt(6,mPart->getCombatPoints());
				pstmt->setString(7,mPart->getMeshFile());
				pstmt->execute();
				delete pstmt;

				Ogre::String str="SELECT MAX(ID) from parts;";
				sql::ResultSet *res = getCoreManager()->readSql(str);
				while(res->next())
					mPart->setID(res->getInt(1));
				delete res;
				//Factors
				//-----------------------------------------------------------------
				//Armor
				GameFactor* factor=mPart->getArmor();
				const StringSet* factorTypes=getCoreManager()->getDamageTypes();
				for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_armor_factors(PartID,ArmorType,Factor) VALUES(?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setString(2,*itr);
					pstmt->setInt(3,factor->getByType(*itr));
					pstmt->execute();
					delete pstmt;
				}
				//Damage (if Weapon)
				if (mPart->getPartType().compare("Weapon")==0)
				{
					factor=static_cast<Weapon*>(mPart)->getDamage();
					for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
					{
						
						pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_damage_factors(PartID,DamageType,Factor) VALUES(?,?,?);");
						pstmt->setInt(1,mPart->getID());
						pstmt->setString(2,*itr);
						pstmt->setInt(3,factor->getByType(*itr));
						pstmt->execute();
						delete pstmt;
					}
				}
				//Speed
				factor=mPart->getSpeed();
				factorTypes=getCoreManager()->getTerrainTypes();
				for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_speed_factors(PartID,TerrainType,Factor) VALUES(?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setString(2,*itr);
					pstmt->setInt(3,factor->getByType(*itr));
					pstmt->execute();
					delete pstmt;
				}
				//------------------------------------------------------------------
				//Technologies
				TechnologyMap* technologies = mPart->getTechnologies();
				for(TechnologyMapIterator itr=technologies->begin();itr!=technologies->end();itr++)
				{
					sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_technology(PartID,TechnologyID,Level) VALUES(?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setInt(2,itr->first);
					pstmt->setInt(3,itr->second->getLevel());
					pstmt->execute();
					delete pstmt;
				}
				//Child nodes
				//--------------------------------------------------------------
				PartNodeArray* nodes=mPart->getChildNodes();
				for(PartNodeArrayIterator itr= nodes->begin();itr!=nodes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_child_nodes(PartId,Type,SubType,NodePozX,NodePozY,NodePozZ \
																				,NodeRotW,NodeRotX,NodeRotY,NodeRotZ,NodeSclX,NodeSclY,NodeSclZ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setString(2,(*itr)->getType());
					pstmt->setString(3,(*itr)->getSubType());
					pstmt->setDouble(4,(*itr)->getPosition().x);
					pstmt->setDouble(5,(*itr)->getPosition().y);
					pstmt->setDouble(6,(*itr)->getPosition().z);
					pstmt->setDouble(7,(*itr)->getOrientation().w);
					pstmt->setDouble(8,(*itr)->getOrientation().x);
					pstmt->setDouble(9,(*itr)->getOrientation().y);
					pstmt->setDouble(10,(*itr)->getOrientation().z);
					pstmt->setDouble(11,(*itr)->getScale().x);
					pstmt->setDouble(12,(*itr)->getScale().y);
					pstmt->setDouble(13,(*itr)->getScale().z);
					pstmt->execute();
					delete pstmt;

					getCoreManager()->addPart(mPart);
				}
				return true;
			}
			bool _updatePart(const CEGUI::EventArgs & arg)
			{
				//Write Part to database
				sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("UPDATE parts SET Name='?',Description='?',Type='?',SubType='?',HitPoints='?',CombatPoints='?',MeshFile='?' WHERE ID='?';");
				
				pstmt->setString(1,mPart->getName());
				pstmt->setString(2,mPart->getDescriprion());
				pstmt->setString(3,mPart->getPartType());
				pstmt->setString(4,mPart->getPartSubType());
				pstmt->setInt(5,mPart->getHitPoints());
				pstmt->setInt(6,mPart->getCombatPoints());
				pstmt->setString(7,mPart->getMeshFile());
				pstmt->setInt(8,mPart->getID());
				pstmt->execute();
				delete pstmt;

				//Factors
				//-----------------------------------------------------------------
				//Armor
				GameFactor* factor=mPart->getArmor();
				const StringSet* factorTypes=getCoreManager()->getDamageTypes();
				for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("UPDATE part_armor_factors SET Factor='?' WHERE PartID='?' AND ArmorType='?';");
					pstmt->setInt(1,factor->getByType(*itr));
					pstmt->setInt(2,mPart->getID());
					pstmt->setString(3,*itr);
					pstmt->execute();
					delete pstmt;
				}
				//Damage (if Weapon)
				if (mPart->getPartType().compare("Body")==0)
				{
					factor=static_cast<Weapon*>(mPart)->getDamage();
					for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
					{

						pstmt = getCoreManager()->getConnection()->prepareStatement("UPDATE part_damage_factors SET Factor='?' WHERE PartID='?' AND DamageType='?';");
						pstmt->setInt(1,factor->getByType(*itr));
						pstmt->setInt(2,mPart->getID());
						pstmt->setString(3,*itr);
						pstmt->execute();
						delete pstmt;
					}
				}
				//Speed
				factor=mPart->getSpeed();
				factorTypes=getCoreManager()->getTerrainTypes();
				for(StringSetConstIterator itr=factorTypes->begin();itr!=factorTypes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("UPDATE part_speed_factors SET Factor='?' WHERE PartID='?' AND TerrainType='?';");
					pstmt->setInt(1,factor->getByType(*itr));
					pstmt->setInt(2,mPart->getID());
					pstmt->setString(3,*itr);
					pstmt->execute();
					delete pstmt;
				}
				//------------------------------------------------------------------
				//Technologies
				pstmt = getCoreManager()->getConnection()->prepareStatement("DELETE FROM part_technology WHERE PartID='?';");
				pstmt->setInt(1,mPart->getID());
				pstmt->execute();
				delete pstmt;
				const TechnologyMap* technologies = mPart->getTechnologies();
				for(TechnologyMapConstIterator itr=technologies->begin();itr!=technologies->end();itr++)
				{
					sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_technology(PartID,TechnologyID,Level) VALUES(?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setInt(2,itr->first);
					pstmt->setInt(3,itr->second->getLevel());
					pstmt->execute();
					delete pstmt;
				}
				//Child nodes
				//--------------------------------------------------------------
				pstmt = getCoreManager()->getConnection()->prepareStatement("DELETE FROM part_child_nodes WHERE PartID='?';");
				pstmt->setInt(1,mPart->getID());
				pstmt->execute();
				delete pstmt;
				const PartNodeArray* nodes=mPart->getChildNodes();
				for(PartNodeArrayConstIterator itr= nodes->begin();itr!=nodes->end();itr++)
				{
					pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_child_nodes(PartId,Type,SubType,NodePozX,NodePozY,NodePozZ \
																				,NodeRotW,NodeRotX,NodeRotY,NodeRotZ,NodeSclX,NodeSclY,NodeSclZ) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);");
					pstmt->setInt(1,mPart->getID());
					pstmt->setString(2,(*itr)->getType());
					pstmt->setString(3,(*itr)->getSubType());
					pstmt->setDouble(4,(*itr)->getPosition().x);
					pstmt->setDouble(5,(*itr)->getPosition().y);
					pstmt->setDouble(6,(*itr)->getPosition().z);
					pstmt->setDouble(7,(*itr)->getOrientation().w);
					pstmt->setDouble(8,(*itr)->getOrientation().x);
					pstmt->setDouble(9,(*itr)->getOrientation().y);
					pstmt->setDouble(10,(*itr)->getOrientation().z);
					pstmt->setDouble(11,(*itr)->getScale().x);
					pstmt->setDouble(12,(*itr)->getScale().y);
					pstmt->setDouble(13,(*itr)->getScale().z);
					pstmt->execute();
					delete pstmt;

					getCoreManager()->addPart(mPart);
				}
				return true;
			}
			//------------------------Update the part technologies-------------------------------------
			void UpdatePartTechnologies(int partId,CEGUI::String strC,CEGUI::String strL)
			{
				CEGUI::Combobox *cmboTech = (CEGUI::Combobox*)getWindowManager()->getWindow(strC);
				CEGUI::Window *lblTech = getWindowManager()->getWindow(strL);
				char *cmboText = (char*)cmboTech->getText().c_str();
				int cmboVal = atoi((char *)lblTech->getText().c_str());
				if (cmboTech->getText().compare("")!=0)
				{
					Ogre::String str="SELECT ID from technology WHERE Name='";
					str+=cmboText;
					str+="';";
					sql::ResultSet *res = getCoreManager()->readSql(str);
					while(res->next())
					{
						Technology* tech = new Technology(res->getInt(1),cmboText,cmboVal);
						getMemoryManager()->addPointer(tech,"Technology");
						mPart->addTechnology(tech);
						sql::PreparedStatement* pstmt = getCoreManager()->getConnection()->prepareStatement("INSERT INTO part_technology(PartID,TechnologyID,Level) VALUES(?,?,?);");
						pstmt->setInt(1,partId);
						pstmt->setInt(2,res->getInt(1));
						pstmt->setInt(3,cmboVal);
						pstmt->execute();
						delete pstmt;
					}
					delete res;
				}
				
			}
			//------------------------Update the part technologies-------------------------------------
			bool _update(const CEGUI::EventArgs & arg)
			{
				canSave=true;
				//Name
				CEGUI::Window* wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Name");
				Ogre::String str((char*)wnd->getText().c_str());
				if (str.compare("")==0)
					canSave=false;
				else if (str.compare(mPart->getName())!=0)
				{
					mPart->setName(str);
					saved=false;
				}
				//Description
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Description");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")==0)
					canSave=false;
				else if (str.compare(mPart->getDescriprion())!=0)
				{
					mPart->setDescription(str);
					saved=false;
				}
				//Type
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")==0)
					canSave=false;
				else if (str.compare(mPart->getPartType())!=0)
				{
					Part* newPart;
					if(str.compare("Body")==0)
						newPart= new Body(mPart->getID(),mPart->getName(),mPart->getDescriprion(),mPart->getPartSubType(),mPart->getMeshFile(),mPart->getHitPoints(),mPart->getCombatPoints());
					if(str.compare("Movement")==0)
						newPart= new Movement(mPart->getID(),mPart->getName(),mPart->getDescriprion(),mPart->getPartSubType(),mPart->getMeshFile(),mPart->getHitPoints(),mPart->getCombatPoints());
					if(str.compare("weapon")==0)
					{
						newPart= new Weapon(mPart->getID(),mPart->getName(),mPart->getDescriprion(),mPart->getPartSubType(),mPart->getMeshFile(),mPart->getHitPoints(),mPart->getCombatPoints());
						static_cast<Weapon*>(newPart)->setDamage(static_cast<Weapon*>(mPart)->getDamage());
					}
					getMemoryManager()->addPointer(newPart,"Part");
					newPart->setArmor(mPart->getArmor());
					newPart->setSpeed(mPart->getSpeed());
					newPart->setTechnologies(mPart->getTechnologies());
					newPart->setChildNodes(mPart->getChildNodes());
					getMemoryManager()->removePointer(mPart);
					delete mPart;
					mPart=newPart;
					saved=false;
				}
				//SubType
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/SubType");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")==0)
					canSave=false;
				else if (str.compare(mPart->getPartSubType())!=0)
				{
					mPart->setPartSubType(str);
					saved=false;
				}
				//Technologies
				mPart->clearTechnologies();
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechFirst");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")!=0)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl");
					if(strcmp((char*)wnd->getText().c_str(),"")!=0)
					{
						int techLvl = atoi((char*)wnd->getText().c_str());
						int techID = getCoreManager()->getTechnologyID(str);
						Technology* tech = new Technology(techID,str,techLvl);
						getMemoryManager()->addPointer(tech,"Technology");
						mPart->addTechnology(tech);
						saved=false;
					}
					else
						canSave=false;
				}
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechSecond");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")!=0)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl1");
					if(strcmp((char*)wnd->getText().c_str(),"")!=0)
					{
						int techLvl = atoi((char*)wnd->getText().c_str());
						int techID = getCoreManager()->getTechnologyID(str);
						Technology* tech = new Technology(techID,str,techLvl);
						getMemoryManager()->addPointer(tech,"Technology");
						mPart->addTechnology(tech);
						saved=false;
					}
					else
						canSave=false;
				}
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechThird");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")!=0)
				{
					wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/TechLvl2");
					if(strcmp((char*)wnd->getText().c_str(),"")!=0)
					{
						int techLvl = atoi((char*)wnd->getText().c_str());
						int techID = getCoreManager()->getTechnologyID(str);
						Technology* tech = new Technology(techID,str,techLvl);
						getMemoryManager()->addPointer(tech,"Technology");
						mPart->addTechnology(tech);
						saved=false;
					}
					else
						canSave=false;
				}
				//HitPoints
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/HitPoints");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")==0)
					canSave=false;
				else if (atoi((char*)str.c_str())!=mPart->getHitPoints())
				{
					mPart->setHitPoints(atoi((char*)str.c_str()));
					saved=false;
				}
				//CombatPoints
				wnd = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Points");
				str=(char*)wnd->getText().c_str();
				if (str.compare("")==0)
					canSave=false;
				else if (atoi((char*)str.c_str())!=mPart->getCombatPoints())
				{
					mPart->setCombatPoints(atoi((char*)str.c_str()));
					saved=false;
				}
				return true;
			}
			bool _showFactors(const CEGUI::EventArgs & arg)
			{
				CEGUI::Combobox *cmbo = (CEGUI::Combobox*)getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/PropertyBox/Type");
				if (cmbo->getSelectedItem()->getText().compare("Weapon")==0)
				{
					CEGUI::Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/Damage");
					wnd->show();
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/DamageLbl");
					wnd->show();
				}
				else
				{
					CEGUI::Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/Damage");
					wnd->hide();
					wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/DamageLbl");
					wnd->hide();
				}
				return true;
			}

			bool _updateFactors(const CEGUI::EventArgs & arg)
			{
				//Armor
				const StringSet* DamageTypes = getCoreManager()->getDamageTypes();
				for(unsigned int i=1;i<=DamageTypes->size();i++)
				{
					CEGUI::ProgressBar* wnd = (CEGUI::ProgressBar *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Bar");
					CEGUI::Editbox* val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Val");
					CEGUI::Window* factor = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Armor")+"/Elem"+i+"/Lbl");
					char* str = (char*)val->getText().c_str();
					if(strcmp(str,"")==0)
						canSave=false;
					else if(atoi(str)!=mPart->getArmorByType(Ogre::String((char*)factor->getText().c_str())))
					{
						mPart->setArmorByType(Ogre::String((char*)factor->getText().c_str()),atol(str));
						saved=false;
					}
					float progress = atof(str)/double(pow(10.0,(int)val->getMaxTextLength())-1);
					wnd->setProgress(progress);
				}
				//Damage
				for(unsigned int i=1;i<=DamageTypes->size();i++)
				{
					CEGUI::ProgressBar* wnd = (CEGUI::ProgressBar *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Bar");
					CEGUI::Editbox* val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Val");
					CEGUI::Window* factor = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Damage")+"/Elem"+i+"/Lbl");
					char* str = (char*)val->getText().c_str();
					if(mPart->getPartType().compare("Weapon")==0)
					{
						if(strcmp(str,"")==0)
							canSave=false;
						else if(atoi(str)!=static_cast<Weapon*>(mPart)->getDamageByType(Ogre::String((char*)factor->getText().c_str())))
						{
							static_cast<Weapon*>(mPart)->setDamageByType(Ogre::String((char*)factor->getText().c_str()),atol(str));
							saved=false;
						}
					}
					float progress = atof(str)/double(pow(10.0,(int)val->getMaxTextLength())-1);
					wnd->setProgress(progress);
				}
				//Speed
				const StringSet* TerrainTypes = getCoreManager()->getTerrainTypes();
				for(unsigned int i=1;i<=TerrainTypes->size();i++)
				{
					CEGUI::ProgressBar *wnd = (CEGUI::ProgressBar *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Bar");
					CEGUI::Editbox *val = (CEGUI::Editbox *)getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Val");
					CEGUI::Window* factor = getWindowManager()->getWindow("Sapphire/Frame/MainTab/Tab 3/AdminTab/Tab 2/PartTool/Stats/"+CEGUI::String("Move")+"/Elem"+i+"/Lbl");
					char * str = (char *)val->getText().c_str();
					if(strcmp(str,"")==0)
						canSave=false;
					else if(atoi(str)!=mPart->getSpeedByTerrain(Ogre::String((char*)factor->getText().c_str())))
					{
						mPart->setSpeedByTerrain(Ogre::String((char*)factor->getText().c_str()),atol(str));
						saved=false;
					}
					float progress = atof(str)/double(pow(10.0,(int)val->getMaxTextLength())-1);
					wnd->setProgress(progress);
				}
				return true;
			}

			
			Ogre::SceneManager *mSceneMgr;
			Ogre::SceneNode *mNode;
			Ogre::Entity *mEntity;
			Ogre::Camera *mCamera;
			Ogre::SceneNode *mCamParent;

			PartNodeArray mPartNodes;

			std::vector<CEGUI::Window*> mTabList;
			std::vector<CEGUI::Window*>::iterator mCurrentTab;
			std::vector<ListboxTextItem*> mListItems;
			Part *mPart;

			bool mRotate;
			bool mDolly;

			bool mOverWrite;
			bool saved;
			bool canSave;
			
		};
	}
}


#endif